#include "qexppart.h"

QEXPPart::QEXPPart(QStringList header,QStringList line,quint32 lineNumber)
:m_line(lineNumber)
{
	#ifdef	LOG_ACTIVATED
	__TRACE__
	#endif
	#ifdef	LEAK_ACTIVATED
	__LEAK__
	#endif
	for(int i=0;i<header.size();i++)
		m_properties[header.at(i)] = normalize(line.at(i));

	add(EXP_DESIGNATOR,EXP_PART_REF,RE_DESIGNATOR,1);
	add(EXP_DIRECTORY_NAME,EXP_HEADER,RE_DIRECTORY_PAGE,1);
	add(EXP_PAGE_NAME,EXP_HEADER,RE_DIRECTORY_PAGE,2);

	add(EXP_POWER,EXP_VALUE,RE_POWER,1);
	add(EXP_TOLERANCE,EXP_VALUE,RE_TOLERANCE,1);
	add(EXP_VOLTAGE,EXP_VALUE,RE_VOLTAGE,1);
	add(EXP_CURRENT,EXP_VALUE,RE_CURRENT,1);
//TODO normaliser
	if(get(EXP_DESIGNATOR) == EXP_RESISTOR_DESIGNATOR)
		add(EXP_REAL_VALUE,EXP_VALUE,RE_RESISTOR_VALUE,0);
	else if(get(EXP_DESIGNATOR) == EXP_CAPACITOR_DESIGNATOR)
		add(EXP_REAL_VALUE,EXP_VALUE,RE_CAPACITOR_VALUE,1);
	else if(get(EXP_DESIGNATOR) == EXP_SELF_DESIGNATOR)
		add(EXP_REAL_VALUE,EXP_VALUE,RE_SELF_VALUE,1);
	
	QRegExp reg(RE_METRICS_PACKAGE);
	if(m_properties.contains(EXP_FOOTPRINT))
	{
		reg.indexIn(m_properties[EXP_FOOTPRINT],Qt::CaseInsensitive);
		add(EXP_PACKAGE,reg.cap());
	}

	add(EXP_KEY,buildKey());
}

QEXPPart::~QEXPPart()
{
	#ifdef	LOG_ACTIVATED
	__TRACE__
	#endif
	#ifdef	LEAK_ACTIVATED
	__LEAK__
	#endif
}

QString QEXPPart::rebuild(QStringList header)
{
	#ifdef	LOG_ACTIVATED
	__TRACE__
	#endif
	#ifdef	LEAK_ACTIVATED
	__LEAK__
	#endif
	QString rebuild;
	for(int i=0;i<header.size();i++)
	{
		QString field = header.at(i);
		if(m_properties.contains(field))
		{
			if(m_properties[field] == EXP_UNKNOWN)
				rebuild.append(EXP_VOID);
			else
				rebuild.append(m_properties[header.at(i)]);
			
		}
		else
			rebuild.append(EXP_VOID);
		if(i != header.size()-1)
				rebuild.append(EXP_SEPARATOR);

	}
	return rebuild;
}

void QEXPPart::add(QString properties,QString field,QString regExp, quint32 capture)
{
	#ifdef	LOG_ACTIVATED
	__TRACE__
	#endif
	#ifdef	LEAK_ACTIVATED
	__LEAK__
	#endif
	if(m_properties.contains(field))
	{
		QRegExp reg(regExp);
		reg.setCaseSensitivity(Qt::CaseInsensitive);
		if(-1 != reg.indexIn(m_properties[field]))
			m_properties[properties] = reg.cap(capture);
		else
			m_properties[properties] = EXP_UNKNOWN;
	}
	else
	{
		m_properties[properties] = EXP_UNKNOWN;
	}
}

void QEXPPart::add(QString properties,QString add)
{
	#ifdef	LOG_ACTIVATED
	__TRACE__
	#endif
	#ifdef	LEAK_ACTIVATED
	__LEAK__
	#endif
	if(!add.isEmpty())
		m_properties[properties] = add;
	else
		m_properties[properties] = EXP_UNKNOWN;
}

QString QEXPPart::normalize(QString raw)
{
	#ifdef	LOG_ACTIVATED
	__TRACE__
	#endif
	#ifdef	LEAK_ACTIVATED
	__LEAK__
	#endif
	if(raw == EXP_VOID)
		return EXP_UNKNOWN;

	return raw;
}

bool QEXPPart::equalsTo(QString field,QString compare)
{
	#ifdef	LOG_ACTIVATED
	__TRACE__
	#endif
	#ifdef	LEAK_ACTIVATED
	__LEAK__
	#endif
	if(m_properties.contains(field))
		return m_properties[field] == compare;

	return false;
}

bool QEXPPart::contains(QString field,QString compare)
{
	#ifdef	LOG_ACTIVATED
	__TRACE__
	#endif
	#ifdef	LEAK_ACTIVATED
	__LEAK__
	#endif
	if(m_properties.contains(field))
		return m_properties[field].contains(compare);

	return false;
}


void QEXPPart::replace(QString field, QString replacement)
{
	#ifdef	LOG_ACTIVATED
	__TRACE__
	#endif
	#ifdef	LEAK_ACTIVATED
	__LEAK__
	#endif
	if(m_properties.contains(field))
	{
		if(m_properties[field].endsWith("\n"))
			m_properties[field] = replacement + "\n";
		else
			m_properties[field] = replacement;
	}
}

QString QEXPPart::buildKey()
{
	#ifdef	LOG_ACTIVATED
	__TRACE__
	#endif
	QString key = get(EXP_DESIGNATOR)+"@"+get(EXP_CODE_PLP)+"@"+get(EXP_VALUE)+"@"+get(EXP_REF_MANUFACTURER);
	return key;
}

QString QEXPPart::key(quint8 errors) const
{ 
	if(errors < m_errors.size())
	{
		QErreur* e = m_errors[errors];
		if(e)
			return m_properties[EXP_KEY] +"@"+e->key();
	}
	return m_properties[EXP_KEY]; 
}

QString QEXPPart::get(QString field) const
{
	#ifdef	LOG_ACTIVATED
	__TRACE__
	#endif
	#ifdef	LEAK_ACTIVATED
	__LEAK__
	#endif
	if(m_properties.contains(field))
		return m_properties[field];
	return EXP_UNKNOWN;
}

QString QEXPPart::getNormalized(QString field) const
{
	#ifdef	LOG_ACTIVATED
	__TRACE__
	#endif
	#ifdef	LEAK_ACTIVATED
	__LEAK__
	#endif
	if(m_properties.contains(field))
	{
		if(m_properties[field] != EXP_UNKNOWN)
		{
			QString s = m_properties[field];
			return s.remove('\"');
		}
	}
	return "";
}

void QEXPPart::addError(QErreur* error)
{ 
	#ifdef	LOG_ACTIVATED
	__TRACE__
	#endif
	#ifdef	LEAK_ACTIVATED
	__LEAK__
	#endif
	if(!m_errors.contains(error) )
		m_errors << error; 
}

bool QEXPPart::hasValidKey() const
{
	if(get(EXP_DESIGNATOR) == EXP_UNKNOWN)
		return false;
	
	if(			get(EXP_CODE_PLP) == EXP_UNKNOWN
				&& get(EXP_VALUE) == EXP_UNKNOWN)
		return false;
		
	return true;
}

QErreur* QEXPPart::getError(quint8 index) const
 { 
	if(index<m_errors.size()) 
		return m_errors.at(index);
	else
		return NULL;
}